using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Windows.Media;
using System.Diagnostics;
using System.Reflection;

namespace KeyboardImageViewer
{
	public static class Utilities
	{
		private const string RandomChars = "0123456789abcdefghijklmnopqrstuvwxyz";

		private static Brush color4 = new SolidColorBrush(Color.FromArgb(0xff, 0xb9, 0xff, 0x9b));
		private static Brush color5 = new SolidColorBrush(Color.FromArgb(0xff, 0x43, 0xe0, 0x00));

		public const int CurrentDatabaseVersion = 11;
		public const string UpdateInfoUrl = "http://engy.us/kiv/latest.xml";
		public const string AppDataFolderName = "Keyboard Image Viewer";

		public static FileInfoNameComparer FileInfoNameComparer = new FileInfoNameComparer();

		public static string CurrentVersion
		{
			get
			{
				return Assembly.GetExecutingAssembly().GetName().Version.ToString();
			}
		}

		public static string UpdatesFolder
		{
			get
			{
				string updatesFolder;

				string appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataFolderName);
				updatesFolder = Path.Combine(appDataFolder, "Updates");

				if (!Directory.Exists(updatesFolder))
				{
					Directory.CreateDirectory(updatesFolder);
				}

				return updatesFolder;
			}
		}

		public static int CurrentProcessInstances
		{
			get
			{
				Process[] processList = Process.GetProcessesByName("KeyboardImageViewer");
				return processList.Length;
			}
		}

		public static int CompareVersions(string versionA, string versionB)
		{
			string[] stringPartsA = versionA.Split('.');
			string[] stringPartsB = versionB.Split('.');

			int[] intPartsA = new int[stringPartsA.Length];
			int[] intPartsB = new int[stringPartsB.Length];

			for (int i = 0; i < intPartsA.Length; i++)
			{
				intPartsA[i] = int.Parse(stringPartsA[i]);
			}

			for (int i = 0; i < intPartsB.Length; i++)
			{
				intPartsB[i] = int.Parse(stringPartsB[i]);
			}

			int compareLength = Math.Min(intPartsA.Length, intPartsB.Length);

			for (int i = 0; i < compareLength; i++)
			{
				if (intPartsA[i] > intPartsB[i])
				{
					return 1;
				}
				else if (intPartsA[i] < intPartsB[i])
				{
					return -1;
				}
			}

			if (intPartsA.Length > intPartsB.Length)
			{
				for (int i = compareLength; i < intPartsA.Length; i++)
				{
					if (intPartsA[i] > 0)
					{
						return 1;
					}
				}
			}

			if (intPartsA.Length < intPartsB.Length)
			{
				for (int i = compareLength; i < intPartsB.Length; i++)
				{
					if (intPartsB[i] > 0)
					{
						return 1;
					}
				}
			}

			return 0;
		}

		public static Brush GetColorFromRating(int rating)
		{
			switch (rating)
			{
				case 1:
					return Brushes.Red;
				case 2:
					return Brushes.Orange;
				case 3:
					return Brushes.Yellow;
				case 4:
					return color4;
				case 5:
					return color5;
				default:
					return Brushes.Purple; // To show there was an error
			}
		}

		public static string GetHash(string path)
		{
			MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

			byte[] hash;
			try
			{
				FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
				hash = md5.ComputeHash(stream);
				stream.Close();
			}
			catch (UnauthorizedAccessException)
			{
				return "";
			}

			StringBuilder sb = new StringBuilder();

			foreach (byte b in hash)
			{
				sb.Append(b.ToString("x2"));
			}

			return sb.ToString();
		}

		public static string ConvertBytesToString(long bytes)
		{
			if (bytes < 1024)
			{
				return bytes.ToString() + " bytes";
			}

			if (bytes < 1048576)
			{
				double kilobytes = ((double)bytes) / 1024;

				return kilobytes.ToString(GetFormatForFilesize(kilobytes)) + " KB";
			}

			double megabytes = ((double)bytes) / 1048576;

			return megabytes.ToString(GetFormatForFilesize(megabytes)) + " MB";
		}

		public static List<string> ListFromPipeList(string pipeList)
		{
			if (pipeList == null || pipeList.Length < 2)
			{
				return new List<string>();
			}

			string[] parts = pipeList.Substring(1, pipeList.Length - 2).Split(new char[] { '|' });
			return new List<string>(parts);
		}

		public static string PipeListFromList(IEnumerable<string> list)
		{
			int tagsAdded = 0;

			StringBuilder builder = new StringBuilder();

			foreach (string item in list)
			{
				if (!item.Contains(",") && !item.Contains("|"))
				{
					builder.Append("|");
					builder.Append(item.Trim());

					tagsAdded++;
				}
			}

			if (tagsAdded > 0)
			{
				builder.Append("|");
			}

			return builder.ToString();
		}

		public static string SpaceListFromList(List<string> list)
		{
			StringBuilder builder = new StringBuilder();

			foreach (string listItem in list)
			{
				builder.Append(listItem);
				builder.Append(" ");
			}

			return builder.ToString().Trim();
		}

		public static string CommaListFromList(List<string> list)
		{
			StringBuilder builder = new StringBuilder();

			for (int i = 0; i < list.Count; i++)
			{
				builder.Append(list[i]);

				if (i != list.Count - 1)
				{
					builder.Append(", ");
				}
			}

			return builder.ToString();
		}

		public static string CalculateDependentTags(List<string> tags, List<KeyValuePair<string, string>> dependencyList)
		{
			var dependentTags = new List<string>();

			foreach (KeyValuePair<string, string> dependency in dependencyList)
			{
				if (tags.Contains(dependency.Key))
				{
					dependentTags.Add(dependency.Value);
				}
			}

			return PipeListFromList(dependentTags);
		}

		public static string RemoveTrailingBackslash(string text)
		{
			if (text.Length < 1)
			{
				return text;
			}

			if (text[text.Length - 1] == '\\')
			{
				return text.Substring(0, text.Length - 1);
			}

			return text;
		}

		public static string GetRandomString(int length)
		{
			StringBuilder randomStringBuilder = new StringBuilder();
			Random random = new Random();

			for (int i = 0; i < length; i++)
			{
				randomStringBuilder.Append(RandomChars[random.Next(RandomChars.Length)]);
			}

			return randomStringBuilder.ToString();
		}

		private static string GetFormatForFilesize(double size)
		{
			int digits = 0;
			double num = size;

			while (num > 1.0)
			{
				num /= 10;
				digits++;
			}

			int decimalPlaces = Math.Min(2, 3 - digits);

			return "F" + decimalPlaces;
		}
	}
}
